$outline-width: 2px;
$inactive-color: #ccc;
$disabled-color: #ddd;

.w-switch {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  cursor: pointer;

  &--disabled,
  &--readonly {
    cursor: not-allowed;
    touch-action: initial;
    -webkit-tap-highlight-color: transparent;
  }

  // Hidden checkbox.
  input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    z-index: -100;
    outline: none;
  }

  // Switch.
  &__input {
    position: relative;
    border-radius: 3em;
    width: 2 * $small-form-el-size;
    height: $small-form-el-size;
    display: flex;
    flex: 0 0 auto; // Prevent stretching width or height.
    align-items: center;
    justify-content: center;
    border: $outline-width solid $inactive-color;
    background-color: $inactive-color;
    @include default-transition;
    cursor: inherit;
    box-sizing: initial;

    // Checked state.
    :checked + & {
      border-color: currentColor;
      background-color: currentColor;
    }

    // Thin.
    .w-switch--thin & {
      box-sizing: border-box;
      border: none;
      // border: ($small-form-el-size / 2) solid rgba(255, 255, 255, 0.6);
      height: round(0.7 * $small-form-el-size);
    }
    .w-switch--thin :checked + & {
      background-color: $inactive-color;
    }

    // Disabled.
    .w-switch--disabled & {
      color: $disabled-color;
    }
    .w-switch--disabled :checked + & {
      opacity: 0.5;
    }
  }

  // Thumb.
  &__input:after {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: $small-form-el-size;
    height: $small-form-el-size;
    background-color: #fff;
    border-radius: 100%;
    @include default-transition;

    :checked + & {
      transform: translateX(100%);
    }

    .w-switch--thin & {
      top: -round(0.15 * $small-form-el-size);
      transform: scale(1.1);
      box-shadow: $box-shadow;
    }
    .w-switch--thin :checked + & {
      transform: translateX(100%) scale(1.1);
      background-color: currentColor;
    }
  }

  // The focus outline & ripple on switch activation.
  &__input:before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: $small-form-el-size;
    height: $small-form-el-size;
    background-color: currentColor;
    border-radius: 100%;
    transform: translateX(100%) scale(0);
    opacity: 0;
    pointer-events: none;
    transition: 0.25s ease-in-out;

    .w-switch--thin & {
      top: -round(0.15 * $small-form-el-size);
    }
  }

  &--ripple &__input:before {
    background-color: transparent;
    animation: w-switch-ripple 0.55s 0.15s ease;
  }

  :focus + &__input:before {
    transform: translateX(0) scale(1.8);
    opacity: 0.2;
  }
  :focus:checked + &__input:before {
    transform: translateX(100%) scale(1.8);
  }

  // After ripple reset to default state, then remove the class via js and the
  // `:focus + &__input:before` will re-transition to normal focused outline.
  &--rippled &__input:before {
    transition: none;
    transform: translateX(100%) scale(0);
    opacity: 0;
  }

  &__label {
    display: flex;
    align-items: center;
    cursor: inherit;
    user-select: none;

    .w-switch--disabled & {
      opacity: 0.5;
    }
  }
}

@keyframes w-switch-ripple {
  0% {
    opacity: 0.8;
    transform: translateX(100%) scale(1);
    background-color: currentColor;
  } // Start with visible ripple.
  100% {
    opacity: 0;
    transform: translateX(100%) scale(2.8);
  } // Propagate ripple to max radius and fade out.
}
